package com.tanhua.server.interceptor;

import com.alibaba.fastjson.JSON;
import com.tanhua.common.utils.Cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @Author 王加鑫
 * @Date 2021/09/05 16:25
 * @Since JDK 1.8
 * 响应结果写入缓存
 */
@ControllerAdvice
@Slf4j
public class MyResponseBodyAdvice implements ResponseBodyAdvice {

    @Value("${tanhua.cache.enable}")
    private Boolean enable;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        //开启处于开启状态  是否是get请求  包含了@Cache注解
        if(enable && methodParameter.hasMethodAnnotation(GetMapping.class) && methodParameter.hasMethodAnnotation(Cache.class)){
            return true;
        }
        return false;
    }

    /**
     * 只有supports方法结果为true才会走这个方法
     * @param o
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if(null == o){
            return null;
        }
        try {
            String redisValue = null;
            if(o instanceof String){
                //如果返回值是String类型就强转为String类型好返回结果
                redisValue = (String) o;
            }else {
                //如果返回值不是String类型就用Json为Json字符串
                redisValue = JSON.toJSONString(o);
            }

            //TODO
            String redisKey = RedisCacheInterceptor.createRedisKey(((ServletServerHttpRequest) serverHttpRequest).getServletRequest());
            Cache cache = methodParameter.getMethodAnnotation(Cache.class);
            //缓存的时间单位是秒
            this.redisTemplate.opsForValue().set(redisKey,redisValue,Long.valueOf(cache.time()), TimeUnit.SECONDS);
        } catch (NumberFormatException e) {
            log.error("缓存存储失败",e);
        }
        return o;
    }
}
